// electron/service/TerminalService.ts
import { IPty, spawn } from 'node-pty';
import { PythonRunner } from '../core/PythonRunner';

interface DataListener {
  callback: (data: string) => void;
  dispose: () => void;
  lastData?: string;
  lastSendTime?: number;
}

class TerminalService {
  private ptys = new Map<number, IPty>();
  private dataListeners = new Map<number, DataListener>();

  createPty(id: number): IPty {
    if (!this.ptys.has(id)) {
      const shell =
        process.env.SHELL ||
        (process.platform === 'win32'
          ? process.env.COMSPEC || 'cmd.exe'
          : '/bin/bash');
      const pty = spawn(shell, [], {
        name: 'xterm-color',
        cols: 80,
        rows: 24,
        cwd: process.cwd(),
        env: {
          ...process.env,
          TERM: 'xterm-256color', // ← 关键修复！
        },
      });
      this.ptys.set(id, pty);
    }
    return this.ptys.get(id)!;
  }

  /**
   * 绑定终端数据监听器，自动解绑旧监听器防止重复
   */
  onData(id: number, callback: (data: string) => void) {
    const pty = this.ptys.get(id);
    if (!pty) {
      console.warn(`[TerminalService] onData: PTY not found for id=${id}`);
      return;
    }

    // 取消旧监听
    const oldListener = this.dataListeners.get(id);
    if (oldListener) {
      oldListener.dispose();
      this.dataListeners.delete(id);
    }

    type WrappedCallback = ((data: string) => void) & {
      lastData?: string;
      lastSendTime?: number;
    };

    // 包装回调，做简单去重+节流（防抖）
    const wrappedCallback: WrappedCallback = (data: string) => {
      const now = Date.now();
      const lastData = wrappedCallback.lastData || '';
      const lastSendTime = wrappedCallback.lastSendTime || 0;

      if (data === lastData && now - lastSendTime < 100) {
        return;
      }

      wrappedCallback.lastData = data;
      wrappedCallback.lastSendTime = now;

      callback(data);
    };

    // 绑定监听
    const disposable = pty.onData(wrappedCallback);
    this.dataListeners.set(id, {
      callback: wrappedCallback,
      dispose: disposable.dispose,
    });
  }

  write(id: number, data: string) {
    const pty = this.ptys.get(id);
    if (!pty) {
      console.warn(`[TerminalService] write: PTY not found for id=${id}`);
      return;
    }
    try {
      pty.write(data);
    } catch (error) {
      console.error(`[TerminalService] write error for id=${id}`, error);
    }
  }

  execPythonFile(id: number, filePath: string) {
    const pythonPath = PythonRunner.getPythonExecutablePath();
    const command = `${pythonPath} ${filePath}\r`;
    this.write(id, command);
  }

  resize(id: number, cols: number, rows: number) {
    const pty = this.ptys.get(id);
    if (!pty) {
      console.warn(`[TerminalService] resize: PTY not found for id=${id}`);
      return;
    }
    if (cols <= 0 || rows <= 0) {
      console.warn(
        `[TerminalService] resize invalid size cols=${cols} rows=${rows}`
      );
      return;
    }
    try {
      pty.resize(cols, rows);
    } catch (error) {
      console.error(`[TerminalService] resize error for id=${id}`, error);
    }
  }

  /**
   * 清理资源，包括解绑监听，关闭 pty，删除记录
   */
  dispose(id: number) {
    const pty = this.ptys.get(id);
    if (!pty) return;

    const listener = this.dataListeners.get(id);
    if (listener) {
      listener.dispose();
      this.dataListeners.delete(id);
    }

    try {
      pty.kill();
    } catch (error) {
      console.error(`[TerminalService] dispose kill error for id=${id}`, error);
    }
    this.ptys.delete(id);
  }
}

export default new TerminalService();
